// 处理时间的函数
function format(time){
    let d = new Date();
    d.setTime(time*1000);
    return d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate();
}
/**
 * 
 * @param {String} elem 传递css选择器规则
 * @param {*} typeName 事件处理名称 不带on前缀
 * @param {*} handler 事件处理程序 就是一个函数
 */
 function bind(elem, typeName, handler) {
    // 获取到监听事件的元素，可能传递选择器规则可以匹配多个元素，如果存在多个元素，就没个元素都监听事件
    var elems=document.querySelectorAll(elem);
    elems.forEach(function(dom){
        window.addEventListener? dom.addEventListener(typeName,handler):dom.attachEventListener('on'+typeName,handler)
    }) 
    // 获取到监听事件的元素,可能传递选择器规则可以匹配多个元素，如果存在多个元素 就每个元素都监听事件
    // var elems = document.querySelectorAll(elem);
    // if(window.addEventListener){
    //     // 满足W3C标准的浏览器
    //     elems.forEach(function(dom){
    //         dom.addEventListener(typeName,handler);
    //     })
    // }else{
    //     elems.forEach(function(dom){
    //         dom.attachEvent('on'+typeName,handler);
    //     })
    // }
    
    // elems.forEach(function(dom){
    //     window.addEventListener?dom.addEventListener(typeName,handler): dom.attachEvent('on'+typeName,handler);
    // })
}
/**
 * 
 * @param {*} min 填入数字
 * @param {*} max 填入数字
 * @returns 
 */
 function randomNum(min,max){
    return parseInt(Math.random()*(max+1-min))+min;
}
/**
 * 
 * @param {Object} options 发送请求参数
 */
 function ajax(options){
    //设置默认信息
    let defaults={
        method:'get',//请求方式
        url:'', //请求地址
        data:'', //请求参数
        contentType:'application/x-www-form-urlencoded', //表示设置请求头Content-Type  ,对应的值
        dataType:'json' ,//表示服务端默认返回的数据格式
        callback:function(){}, //表示拿到服务端结果之后的处理方式，是哟个回调函数
    }
    //传参之后需要覆盖默认值
    for(let key in defaults){
        options[key] && (defaults[key]=options[key]);
    }
    //检查每一个参数是否满足要求
    /* 检查url地址是否传递 */
    if(!defaults.url){
        throw new Error('url地址必须传递');
    }
    /* 检查请求方式是否传递 */
    let methodType=['get','post','put','delete'];
    defaults.method=defaults.method.toLocaleLowerCase();
    if(!methodType.includes(defaults.method)){
        throw new Error('请求方式设置错误');
    }
    /*请求参数数据格式是否正确，两种情况，可能是对象，也可能是字符串*/
    let dataClass=Object.prototype.toString.call(defaults.data);
    if(dataClass!='[object String]'&& dataClass!='[object Object]'){
        throw new Error('请求参数格式格式错误');
    }   
    /* 验证回调，要求必须是函数 */
    if(Object.prototype.toString.call(defaults.callback)!='[object Function]'){
        throw new Error('回调必须是一个函数');
    }
    // 构建请求携带的数据，无论是什么情况，转成字符串即可
    let data='';
    if(Object.prototype.toString.call(defaults.data)=='[object string]'){
        data=defaults.data;
    }else{
        //如果是get,delete请求 字符串最终需要放到URL地址上 格式key/value格式，如果是post，put请求 格式 有可能是key/value格式 也可能是JSON格式
        if((defaults.method=='post'||defaults.method=='put')&&defaults.contentType=='application/json'){
            //设置请求参数为JSON格式
            data=JSON.stringify(defaults.data);
        }else{
            for (let key in defaults.data){
                data+=`${key}=${defaults.data[key]}&`
            }
            data=data.substring(0,data.length-1);
        }
    }
    //获取Ajax对象
    let xhr=new XMLHttpRequest;
    //打开连接
    let url=defaults.url
    if((defaults.method=='get'||defaults.method=='delete')&&data){
        url=defaults.url+'?'+data;
    }
    xhr.open(defaults.method,url);
    //发送请求  判断请求方式为post或者put  并且data中有参数需要携带  所以才使用data  否则就传递空
    //设置请求头信息
    xhr.setRequestHeader('Content-Type',defaults.contentType);
    xhr.send(((defaults.method=='post'||defaults.method=='put')&&data)?data:'');
    //监听状态改变
    xhr.onreadystatechange=function(){
        if(xhr.status==200&&xhr.readyState==4){
            let response=(defaults.dataType=='json')?JSON.parse(xhr.responseText):xhr.responseText;
            defaults.callback(response);
        }
    }
}
/**
 * 设置cookie
 * @param {String} key cookie的名称
 * @param {String} value  cookie的值
 * @param {Number} expires 传递过期时间，单位为秒  默认值0表示关闭浏览器失效
 */
 function setCookie(key,value,expires=0){
    if(expires == 0){
        document.cookie = `${key}=${value};path=/`;
    }else{
        let d = new Date();
        d.setTime( d.getTime() - 8 * 3600 *1000 + expires * 1000);
        document.cookie = `${key}=${value};path=/;expires=${d}`;
    }
}
/**
 * 删除cookie
 * @param {String} key cookie的名称
 */
function removeCookie(key){
    setCookie(key,'',-1);
}
/**
 * 获取cookie的值
 * @param {String} key cookie的名称 
 */
function getCookie(key){
    let value = '';
    document.cookie.split('; ').forEach(item=>{
        let keyVlue = item.split('=')
        if(key == keyVlue[0]){
            value = keyVlue[1];
        }
    })
    return value;
}
/**
 * 
 * @param {*} name 
 * @param {*} age 
 * @param {*} gender 
 * @returns 
 */
 function createPerson(name,age,gender){
    var obj={
        name:name,
        age:age,
        gender:gender,
        sayname:function(){
            console.log(this.name);
        }
    }
    return obj;
}
/**
 * 获取标签指定的的样式
 * @param {Document} elem 需要获取样式的元素的dom对象
 * @param {String} attr 获取样式的名称
 * @returns String
 */
 function getStyle(elem,attr){
    if(window.getComputedStyle){
        // 表示window下存在getComputedStyle属性 说明绝对是IE高版本
        return window.getComputedStyle(elem)[attr];
    }
    // 代码走到这里绝对可以证明是IE低版本
    return elem.currentStyle[attr];
}

/**
 * 从URL地址中获取指定名称的参数
 * @param {String} key 要获取参数的名称
 * @returns 
 */
 function getUrlParam(key){
    var result;
    // 截取字符串
    location.search.substring(1).split('&').forEach(function(item){
        // console.log(item)
        var keyValue = item.split('=');
        if(keyValue[0] == key){
            result = keyValue[1];
        }
    })
    return result;
}

/**
 * 
 * @param {String|Document} elem 
 * @param { Object} options 
 */
 function Page(elem, options,callback) {
    this.callback=callback;
    //使用容器保存dom对象
    this.elem = (Object.prototype.toString.call(elem) == '[object String]') ? document.querySelector(elem) : elem;
    this.inputDom = null;
    this.listDom = null;
    this.initialFigure = {
        language: {
            firstPage: '<<',
            previousPage: '<',
            list: '',
            nextPage: '>',
            lastPage: '>>'
        },
        data: {
            total: 100,//数据总条数
            pageSize: 10//每页的数量
        }
    }
    this.mergeFigure(options);
    this.totalPage = Math.ceil(this.initialFigure.data.total / this.initialFigure.data.pageSize);
    this.currentPage = 1;
    this.elementAdd();
    this.executeEvent();

}
//传参修改默认值
Page.prototype.mergeFigure = function (options) {
    for (let key in this.initialFigure.language) {
        options.language[key] && (this.initialFigure.language[key] = options.language[key])
    }
    for (let key in this.initialFigure.data) {
        options.data[key] && (this.initialFigure.data[key] = options.data[key])
    }
}
//元素的添加
Page.prototype.elementAdd = function () {
    this.elem.innerHTML = '';
    this.createOutside();
    this.createNumber();
    this.createSearchElement();
    console.log('elementAdd=代码执行了吗？', this.totalPage)
    Object.prototype.toString.call(this.callback) == '[object Function]' && this.callback(this.currentPage);
}
//创建外层div的方法
Page.prototype.createOutside = function () {
    for (let key in this.initialFigure.language) {
        let divDom = document.createElement('div');
        // 设置样式名称 后期用户需要针对分页进行样式控制 可以自己根据样式名称编写样式
        divDom.className = key;
        // 如果是存储数字页的容器使用对象属性保存 保存的目的是为了方便后期使用(避免在页面上寻找list的元素)
        key == 'list' && (this.listDom = divDom);
        divDom.innerHTML = this.initialFigure.language[key];
        console.log(this.elem);
        this.elem.appendChild(divDom);
    }
}
//创建中间数字的
Page.prototype.createNatureNumber = function (start, end) {
    console.log('代码执行了吗？')
    for (let i = start; i <= end; i++) {
        let pDom = document.createElement('p');
        i == this.currentPage && (pDom.className = 'active')
        pDom.innerHTML = i;
        this.listDom.appendChild(pDom);
        console.log(this.listDom);
    }
}
//传入对应参数-----------------------------------备注：待会儿，重新写，现在写，效果凸显不出来
Page.prototype.createNumber = function () {
    if (this.totalPage <= 5) {
        this.createNatureNumber(1, this.totalPage);
    } else {
        if (this.currentPage <= 3) {
            this.createNatureNumber(1, 5);
        } else if (this.currentPage >= this.totalPage - 2) {
            this.createNatureNumber(this.totalPage - 4, this.totalPage);
        } else {
            this.createNatureNumber(this.currentPage - 2, this.currentPage + 2);
        }
    }
}
//点击事件绑定函数
Page.prototype.executeEvent = function () {
    this.elem.addEventListener('click', event => {
        console.log(this.elem);
        switch (event.target.className) {
            case 'firstPage':
                this.currentPage = 1;
                this.elementAdd();
                break;
            case 'previousPage':
                if (this.currentPage > 1) {
                    this.currentPage -= 1;
                    this.elementAdd();
                }
                break;
            case 'nextPage':
                if (this.currentPage < this.totalPage) {
                    this.currentPage += 1;
                    this.elementAdd();
                }
                break;
            case 'lastPage':
                this.currentPage = this.totalPage;
                this.elementAdd();
                break;
            default:
                if (event.target.nodeName == 'P') {
                    this.currentPage = Number(event.target.innerHTML);
                    this.elementAdd();
                } else if (event.target.nodeName == 'BUTTON') {
                    // 获取到当前输入的值
                    let num = parseInt(this.inputDom.value);
                    if (num > 0 && num < this.totalPage) {
                        this.currentPage = num;
                        this.elementAdd();
                    }
                }
        }
    })
}
//添加搜索事件
Page.prototype.createSearchElement = function () {
    this.inputDom = document.createElement('input');
    this.inputDom.style.width = '60px';
    this.inputDom.style.marginRight = '20px';
    this.elem.appendChild(this.inputDom);
    console.log('代码执行了吗？')
    let btnDom = document.createElement('button');
    btnDom.innerHTML = 'seach';
    this.elem.appendChild(btnDom);
    this.elem.addEventListener('click', event => {
    })
}


/**
 * 
 * @param {Document} elem dom对象 
 * @param {String} obj 
 * @returns String
 */
 function setStyle(elem,obj){
    if(Object.prototype.toString.call(obj) != '[object Object]'){
        return;
    }
    for(var key in obj){
       elem.style[key]=obj[key];
    }
    }

/**
 * 多属性运动解决动画执行结束问题
 * @param {Document} elem 运动元素的dom对象
 * @param {Object} targets 使用对象形式表示需要运动那些属性 其中属性名称是运动的样式名称 属性值表示运动目标点 {left：200，top：200} 
 */
 function animate(elem,targets,callback){
    // 如果开始针对元素 设置向右移动 ，在动画还未执行完毕之前设置元素 向左移动，导致结果运算左右抖动。解决办法 在每次调用animate就将前面没有执行完毕的定时器 清除掉 借助于dom对象记住上一次定时器的标识
    clearInterval(elem.timer);
    elem.timer = setInterval(()=>{
        for(let key in targets){
            // 获取到当前循环的属性名称对应的样式值是多少  对于透明度取出的值是0-1之间的小数 。所以放大1000倍
            let currentStyle = (key == 'opacity')? parseFloat(getStyle(elem,key))*1000:  parseInt(getStyle(elem,key));
            // 获取到当前循环运动样式的终止点  透明度用户传递的是0-1之间的小数 也放大1000倍
            let target = (key =='opacity')? targets[key]*1000:targets[key];
            let speed = (target-currentStyle>0)? Math.ceil((target-currentStyle)*0.03):Math.floor((target-currentStyle)*0.03);
            if(currentStyle == target){
                delete targets[key];// 每次判断一个key达到终止点 就属性就从targets移除
                if(Object.keys(targets).length == 0){
                    console.log('运动执行全结束')
                    clearInterval(elem.timer)
                    // 在封装函数时 动画什么时候执行结束 只有封装的函数代码中可以判断。如果需要继续向下运动 所以 可以再次调用自身,但是如果直接这么调用自身 函数就不具备通用性
                    // animate(elem,{top:300})
                    // 判断callback 是不是函数 如果是函数 就将函数调用起来
                    Object.prototype.toString.call(callback) == '[object Function]' && callback();
                }
            }else{
                // 由于前面 当前样式的值与目标都放大了1000倍 所以在设置时缩小1000倍
                elem.style[key] = (key == 'opacity')?(currentStyle + speed)/1000: currentStyle + speed + 'px';
            }
        }
    },20)
}
/**
 * 
 * @param {Document} elem  运动元素的dom对象
 * @param {Object} targets  使用对象形式表示需要运动那些属性，其中名称时运动的样式名称
 * 属性值表示运动目标点
 */
 function moreAttrSportV3(elem,targets){
    let timer=setInterval(()=>{
        for(let key in targets){
            let currentStyle=(key=='opacity')?parseFloat(getStyle(elem,key)*1000):parseInt(getStyle(elem,key));
            let target=(key=='opacity')?targets[key]*1000:targets[key]
            let speed=target-currentStyle>0?Math.ceil((target-currentStyle)*0.03):Math.floor((target-currentStyle)*0.03);
            if(currentStyle==target){
                delete target;
                if(Object.keys(targets).length==0){
                    clearInterval(timer);
                }
            }else{
                elem.style[key]=(key=='opacity')?(currentStyle+speed)/1000:(currentStyle+speed+'px');
            }
        }
    })
}
/**
 * 
 * @param {Document} elem  运动元素的dom对象
 * @param {Object} targets  使用对象形式表示需要运动那些属性，其中名称时运动的样式名称
 * 属性值表示运动目标点
 */
 function moreAttrSportV2(elem,targets){
    let timer=setInterval(()=>{
        for(let key in targets){
            let currentStyle=parseInt(getStyle(elem,key))
            let speed=targets[key]-currentStyle>0?Math.ceil((targets[key]-currentStyle)*0.03):Math.floor((targets[key]-currentStyle)*0.03);
            if(currentStyle==targets[key]){
                delete targets[key];
                if(Object.keys(targets).length==0){
                    clearInterval(timer);
                }
            }else{
                elem.style[key]=currentStyle+speed+'px';
            }
        }
    })
}
/**
 * 
 * @param {Document} elem  运动元素的dom对象
 * @param {Object} targets  使用对象形式表示需要运动那些属性，其中名称时运动的样式名称
 * 属性值表示运动目标点
 */
 function moreAttrSportV1(elem,targets){
    let timer=setInterval(()=>{
        for(let key in targets){
            let currentStyle=parseInt(getStyle(elem,key))
            if(currentStyle==targets[key]){
                delete targets[key];
                console.log('lalal');
                if(Object.keys(targets).length==0){
                    clearInterval(timer);
                }
            }else{
                elem.style[key]=currentStyle+5+'px';
            }
        }
    })
}
/**
 * 
 * @param {Document} elem 要运动元素的dom对象 
 * @param {String} attr 运动的样式名称
 * @param {Number} target 运动的目的地
 */
function simpleSport(elem,attr,target){
 let timer=setInterval(()=>{
    let currentStyle=parseInt(getStyle(elem,attr));
    if(currentStyle==target){
        clearInterval(timer);
    }else{
        elem.style[attr]=currentStyle+5+'px';
    }
 },20);
}
